// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

#region File Description
//-----------------------------------------------------------------------------
// AudioManager.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
#endregion

namespace CF.Framework.Engine.Misc
{
	/// <summary>
	/// Component that manages audio playback for all sounds.
	/// </summary>
	public class AudioManager : GameComponent
	{
		private Dictionary<string, AudioObject> objects;

		internal AudioManager()
			: base(GameApp.Current)
		{
			objects = new Dictionary<string, AudioObject>();
		}

		public AudioObject Load<T>(string assetName)
		{
			AudioObject obj = new AudioObject(assetName, Game.Content.Load<T>(assetName));
			obj.Manager = this;

			objects.Add(assetName, obj);

			return obj;
		}

		public void UnloadContent()
		{
			foreach (AudioObject obj in objects.Values)
			{
				if (obj.AssetObject is IDisposable)
				{
					(obj.AssetObject as IDisposable).Dispose();
				}
			}

			objects.Clear();
		}

		public void Play(AudioObject obj)
		{
			Play(obj, true);
		}

		public void Play(AudioObject obj, bool isRepeating)
		{
			if (obj.AssetObject is SoundEffect)
			{
				((SoundEffect)obj.AssetObject).Play();
			}
			else if (obj.AssetObject is SoundEffectInstance)
			{
				((SoundEffectInstance)obj.AssetObject).Play();
			}
			else if (obj.AssetObject is Song)
			{
				MediaPlayer.IsRepeating = isRepeating;
				MediaPlayer.Play(obj.AssetObject as Song);
			}
		}

		public void Play(string assetName)
		{
			Play(assetName, true);
		}

		public void Play(string assetName, bool isRepeating)
		{
			if (objects.ContainsKey(assetName))
			{
				var obj = objects[assetName];

				Play(obj, isRepeating);
			}
		}

		public void Stop(AudioObject obj)
		{
			if (obj.AssetObject is SoundEffectInstance)
			{
				((SoundEffectInstance)obj.AssetObject).Pause();
			}
			else if (obj.AssetObject is Song)
			{
				MediaPlayer.IsRepeating = false;
				MediaPlayer.Stop();
			}
		}

		public void Stop(string assetName)
		{
			if (objects.ContainsKey(assetName))
			{
				var obj = objects[assetName];

				Stop(obj);
			}
		}

		public void Pause(AudioObject obj)
		{
			if (obj.AssetObject is SoundEffectInstance)
			{
				((SoundEffectInstance)obj.AssetObject).Pause();
			}
			else if (obj.AssetObject is Song)
			{
				MediaPlayer.Pause();
			}
		}

		public void Pause(string assetName)
		{
			if (objects.ContainsKey(assetName))
			{
				var obj = objects[assetName];

				Pause(obj);
			}
		}

		public void Resume(AudioObject obj)
		{
			Resume(obj, true);
		}

		public void Resume(AudioObject obj, bool isRepeating)
		{
			if (obj.AssetObject is SoundEffectInstance)
			{
				((SoundEffectInstance)obj.AssetObject).Pause();
			}
			else if (obj.AssetObject is Song)
			{
				if (MediaPlayer.Queue.ActiveSong != obj.AssetObject)
				{
					Play(obj, isRepeating);
				}
				else
				{
					MediaPlayer.IsRepeating = isRepeating;
					MediaPlayer.Resume();
				}
			}
		}

		public void Resume(string assetName)
		{
			Resume(assetName, true);
		}

		public void Resume(string assetName, bool isRepeating)
		{
			if (objects.ContainsKey(assetName))
			{
				var obj = objects[assetName];

				Resume(obj, isRepeating);
			}
		}

		public static void Stop()
		{
			MediaPlayer.IsRepeating = false;
			MediaPlayer.Stop();
		}
	}
}